package com.bugbuff.dubbo.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.PageUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.bugbuff.common.mapper.UserInfoMapper;
import com.bugbuff.common.pojo.Admin;
import com.bugbuff.common.pojo.UserInfo;
import com.bugbuff.common.utils.AdminThreadLocal;
import com.bugbuff.dubbo.server.api.MessageApi;
import com.bugbuff.dubbo.server.api.QuanZiApi;
import com.bugbuff.dubbo.server.api.VideoApi;
import com.bugbuff.dubbo.server.enums.HtTotals;
import com.bugbuff.dubbo.server.pojo.Message;
import com.bugbuff.dubbo.server.pojo.Publish;
import com.bugbuff.dubbo.server.pojo.Video;
import com.bugbuff.dubbo.server.vo.*;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
@Slf4j
public class MessageService {

    @Reference
    private MessageApi messageApi;

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Reference
    private VideoApi videoApi;

    @Reference
    private QuanZiApi quanZiApi;

    /**
     * 消息拒绝
     * @param list 视频或者动态的主键id集合，通过new ObjectId()转化类型存储到MongoDB中
     * @return
     */
    public String reject(List<String> list) {

        Long userId = AdminThreadLocal.get().getUid();
        String message = null;
        for (String publishId : list) {
             message = messageApi.rejectMessage(userId,publishId);

             quanZiApi.updateSeeType(publishId,2);

            if (StrUtil.isEmpty(message)){
                return null;
            }
        }

        return message;

    }

    /**
     * 消息通过
     * @param list
     * @return
     */
    public String pass(List<String> list) {

        Long userId = AdminThreadLocal.get().getUid();
        String message = null;
        for (String publishId : list) {
            message = messageApi.passMessage(userId,publishId);
            quanZiApi.updateSeeType(publishId,1);
            if (StrUtil.isEmpty(message)){
                return null;
            }
        }

        return message;
    }

    /**
     * 消息置顶
     * @param messageId
     * @return
     */
    public String top(String messageId) {

        Long userId = AdminThreadLocal.get().getUid();
        try {
            String message = messageApi.top(userId,messageId);
            if (StrUtil.isNotEmpty(message)){
                Map<String, String> map = new HashMap<>();
                map.put("message", "操作成功");
                return JSONUtil.toJsonStr(map);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("消息置顶失败");
        }

        return null;
    }

    /**
     * 消息取消置顶
     * @param messageId
     * @return
     */
    public String unTop(String messageId) {

        Long userId = AdminThreadLocal.get().getUid();
        try {
            String message = messageApi.unTop(userId,messageId);
            if (StrUtil.isNotEmpty(message)){
                Map<String, String> map = new HashMap<>();
                map.put("message", "操作成功");
                return JSONUtil.toJsonStr(map);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("消息置顶失败");
        }

        return null;
    }

    /**
     * 根据消息id查询消息
     * @param messageId
     * @return
     */
    public MessageVo getMessageByMessage(String messageId) {

        try {
            Message message = messageApi.getMessageByMessage(messageId);
            MessageVo messageVo = new MessageVo();
            if (ObjectUtil.isNotEmpty(message)) {
                Integer publishUserId = message.getPublishUserId();
                LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(UserInfo::getUserId, publishUserId);
                UserInfo userInfo = userInfoMapper.selectOne(wrapper);
                messageVo.setNickname(userInfo.getNickName());
                messageVo.setUserId(publishUserId);
                messageVo.setUserLogo(userInfo.getLogo());
                messageVo.setState(message.getState().toString());
                messageVo.setTopState(message.getTopState());
            }

            //2.查询动态补充剩余的属性
            Publish publish = quanZiApi.queryPublishById(message.getPublishId().toHexString());

                messageVo.setId(message.getPublishId().toHexString());
                messageVo.setCreateDate(publish.getCreated());
                messageVo.setText(publish.getText());
                messageVo.setMedias(publish.getMedias());
                messageVo.setCommentCount(Convert.toInt(quanZiApi.queryCommentCount(message.getPublishId().toHexString())));
                messageVo.setLikeCount(Convert.toInt(quanZiApi.queryLikeCount(message.getPublishId().toHexString())));
                messageVo.setReportCount(5);
                messageVo.setForwardingCount(13);

                return messageVo;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("查询消息详情失败！");
        }
        return null;
    }

    /**
     * 消息撤销
     * @return
     */
    public String revocationMessage(List<String> list) {

        Long userId = AdminThreadLocal.get().getUid();

        String message =null;

        for (String publishId : list) {

            message = messageApi.revocationMessage(userId,publishId);
            quanZiApi.updateSeeType(publishId,2);
            if (StrUtil.isEmpty(message)){
                return null;
            }
        }

        return message;
    }

    /**
     * 消息翻页
     * @param page
     * @param pagesize
     * @param sortProp
     * @param sortOrder
     * @param id
     * @param sd
     * @param ed
     * @param uid
     * @param state
     * @return
     */
    public MessagePageResult getMessagePage(Integer page, Integer pagesize, String sortProp, String sortOrder, String id, Long sd, Long ed, Long uid, Integer state) {

        if (uid == null) {//动态审核
            MessagePageResult messagePageResult = new MessagePageResult();
            messagePageResult.setPage(page);
            messagePageResult.setPagesize(pagesize);


            List<Message> messageList = messageApi.getMessagePage(page, pagesize, sortProp, sortOrder, id, sd, ed, uid, state);
            if (CollUtil.isEmpty(messageList)) {
                return null;
            }

            List<MessageVo> messageVoList = new ArrayList<>();

            List<TotalVo> totalVoList = new ArrayList();
            if (state == 0 || state == null) {
                Integer value0 = messageApi.queryAllState(HtTotals.PEOPLE_CHECK) + messageApi.queryAllState(HtTotals.PEOPLE_PASS) + messageApi.queryAllState(HtTotals.PEOPLE_REJECT);
                messagePageResult.setCounts(value0);
                messagePageResult.setPages(value0 % pagesize == 0 ? value0 / pagesize : value0 / pagesize + 1);//messageList.size()/pagesize
            } else if (state == 3) {
                Integer value3 = messageApi.queryAllState(HtTotals.PEOPLE_CHECK);
                messagePageResult.setCounts(value3);
                messagePageResult.setPages(value3 % pagesize == 0 ? value3 / pagesize : value3 / pagesize + 1);//messageList.size()/pagesize

            } else if (state == 4) {
                Integer value4 = messageApi.queryAllState(HtTotals.PEOPLE_REJECT);
                messagePageResult.setCounts(value4);
                messagePageResult.setPages(value4 % pagesize == 0 ? value4 / pagesize : value4 / pagesize + 1);//messageList.size()/pagesize
            } else if (state == 5) {
                Integer value5 = messageApi.queryAllState(HtTotals.PEOPLE_PASS);
                messagePageResult.setCounts(value5);
                messagePageResult.setPages(value5 % pagesize == 0 ? value5 / pagesize : value5 / pagesize + 1);//messageList.size()/pagesize
            }

            for (Message message : messageList) {
                MessageVo messageVo = getMessageByMessage(message.getId().toHexString());
                messageVoList.add(messageVo);
            }

            TotalVo totalVo0 = new TotalVo();
            totalVo0.setTitle("全部");
            totalVo0.setCode("0");
            totalVo0.setValue(messageApi.queryAllState(HtTotals.PEOPLE_CHECK) + messageApi.queryAllState(HtTotals.PEOPLE_PASS) + messageApi.queryAllState(HtTotals.PEOPLE_REJECT));
            totalVoList.add(totalVo0);

            TotalVo totalVo3 = new TotalVo();
            totalVo3.setTitle("待审核");
            totalVo3.setCode("3");
            totalVo3.setValue(messageApi.queryAllState(HtTotals.PEOPLE_CHECK));
            totalVoList.add(totalVo3);

            TotalVo totalVo5 = new TotalVo();
            totalVo5.setTitle("已通过");
            totalVo5.setCode("5");
            totalVo5.setValue(messageApi.queryAllState(HtTotals.PEOPLE_PASS));
            totalVoList.add(totalVo5);

            TotalVo totalVo4 = new TotalVo();
            totalVo4.setTitle("已驳回");
            totalVo4.setCode("4");
            totalVo4.setValue(messageApi.queryAllState(HtTotals.PEOPLE_REJECT));
            totalVoList.add(totalVo4);

            messagePageResult.setItems(messageVoList);

            messagePageResult.setTotals(totalVoList);
            return messagePageResult;

        } else {//查询个人动态

//            查询个人动态列表
            List<Message> messageList = messageApi.findPublishByUid(uid, page, pagesize, sortProp, sortOrder);
            if (ObjectUtil.isNull(messageList))
//                直接返回null前端报错，没发过动态的躺枪
//                messageList = Collections.emptyList();
                return MessagePageResult.builder().page(1).pages(1).counts(0).pagesize(1).items(Collections.emptyList()).build();


//            封装分页对象
            MessagePageResult messagePageResult = new MessagePageResult();
            messagePageResult.setPage(page);
            messagePageResult.setPagesize(pagesize);
            Integer counts = Convert.toInt(messageApi.countPublishByUid(uid));
            messagePageResult.setCounts(counts);
//            messagePageResult.setPages(count%pagesize==0?count/pagesize:count/pagesize+1);
            messagePageResult.setPages(PageUtil.totalPage(counts, pagesize));


//            封装前端映射对象
            List<MessageVo> messageVoList = new ArrayList<>();
            for (Message message : messageList) {
                MessageVo messageVo = getMessageByMessage(message.getId().toHexString());
                messageVoList.add(messageVo);
            }

//            对集合中的vo对象集合根据字段用比较器进行排序
            List<MessageVo> sortedVoList = CollUtil.sort(messageVoList, getComparator(sortProp, sortOrder));

//            查找到所有置顶消息
            List<Message> top = messageApi.findTop(uid);
            if (CollUtil.isEmpty(top)) {
                int[] arr = PageUtil.transToStartEnd(page - 1, pagesize);
                List<MessageVo> sub = ListUtil.sub(sortedVoList, arr[0], arr[1]);
                messagePageResult.setItems(sub);
                return messagePageResult;
            }

//            封装置顶消息vo对象
            List<MessageVo> topVoList = new ArrayList<>();
            for (Message message : top) {
                MessageVo messageVo = getMessageByMessage(message.getId().toHexString());
                topVoList.add(messageVo);
            }

//            拼接两个vo集合并且进行分页截取
            topVoList.addAll(sortedVoList);
            int[] arr = PageUtil.transToStartEnd(page - 1, pagesize);
            List<MessageVo> sub = ListUtil.sub(topVoList, arr[0], arr[1]);

//            返回
            messagePageResult.setItems(sub);
            return messagePageResult;
        }

    }

    /**
     * 比较器排序
     *
     * @param sortProp
     * @param sortOrder
     * @return
     */
    private Comparator<MessageVo> getComparator(String sortProp, String sortOrder) {
        switch (sortProp) {
            case "createDate":
                if (StrUtil.equals("ascending", sortOrder)) {
                    return new Comparator<MessageVo>() {
                        @Override
                        public int compare(MessageVo o1, MessageVo o2) {
                            return o1.getCreateDate().compareTo(o2.getCreateDate());
                        }
                    };
                } else {
                    return new Comparator<MessageVo>() {
                        @Override
                        public int compare(MessageVo o1, MessageVo o2) {
                            return o2.getCreateDate().compareTo(o1.getCreateDate());
                        }
                    };
                }

            case "likeCount":
                if (StrUtil.equals("ascending", sortOrder)) {
                    return new Comparator<MessageVo>() {
                        @Override
                        public int compare(MessageVo o1, MessageVo o2) {
                            return o1.getLikeCount().compareTo(o2.getLikeCount());
                        }
                    };
                } else {
                    return new Comparator<MessageVo>() {
                        @Override
                        public int compare(MessageVo o1, MessageVo o2) {
                            return o2.getLikeCount().compareTo(o1.getLikeCount());
                        }
                    };
                }

            case "commentCount":
                if (StrUtil.equals("ascending", sortOrder)) {
                    return new Comparator<MessageVo>() {
                        @Override
                        public int compare(MessageVo o1, MessageVo o2) {
                            return o1.getCommentCount().compareTo(o2.getCommentCount());
                        }
                    };
                } else {
                    return new Comparator<MessageVo>() {
                        @Override
                        public int compare(MessageVo o1, MessageVo o2) {
                            return o2.getCommentCount().compareTo(o1.getCommentCount());
                        }
                    };
                }

            case "reportCount":
                if (StrUtil.equals("ascending", sortOrder)) {
                    return new Comparator<MessageVo>() {
                        @Override
                        public int compare(MessageVo o1, MessageVo o2) {
                            return o1.getReportCount().compareTo(o2.getReportCount());
                        }
                    };
                } else {
                    return new Comparator<MessageVo>() {
                        @Override
                        public int compare(MessageVo o1, MessageVo o2) {
                            return o2.getReportCount().compareTo(o1.getReportCount());
                        }
                    };
                }

            case "forwardingCount":
                if (StrUtil.equals("ascending", sortOrder)) {
                    return new Comparator<MessageVo>() {
                        @Override
                        public int compare(MessageVo o1, MessageVo o2) {
                            return o1.getForwardingCount().compareTo(o2.getForwardingCount());
                        }
                    };
                } else {
                    return new Comparator<MessageVo>() {
                        @Override
                        public int compare(MessageVo o1, MessageVo o2) {
                            return o2.getForwardingCount().compareTo(o1.getForwardingCount());
                        }
                    };
                }

            default:
                return new Comparator<MessageVo>() {
                    @Override
                    public int compare(MessageVo o1, MessageVo o2) {
                        return o1.getCreateDate().compareTo(o2.getCreateDate());
                    }
                };
        }

    }

    /**
     * 消息详情
     * @param publishId
     * @return
     */
    public MessageVo getPublishByPid(String publishId) {

        try {
            Message message = messageApi.getMessageByPublishId(publishId);
            MessageVo messageVo = new MessageVo();
            if (ObjectUtil.isNotEmpty(message)) {
                Integer publishUserId = message.getPublishUserId();
                LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(UserInfo::getUserId, publishUserId);
                UserInfo userInfo = userInfoMapper.selectOne(wrapper);
                messageVo.setNickname(userInfo.getNickName());
                messageVo.setUserId(publishUserId);
                messageVo.setUserLogo(userInfo.getLogo());
                messageVo.setState(message.getState().toString());
                messageVo.setTopState(message.getTopState());
            }

            //2.查询动态补充剩余的属性
            Publish publish = quanZiApi.queryPublishById(publishId);

            messageVo.setId(publishId);
            messageVo.setCreateDate(publish.getCreated());
            messageVo.setText(publish.getText());
            messageVo.setMedias(publish.getMedias());
            messageVo.setCommentCount(Convert.toInt(quanZiApi.queryCommentCount(message.getPublishId().toHexString())));
            messageVo.setLikeCount(Convert.toInt(quanZiApi.queryLikeCount(message.getPublishId().toHexString())));
            messageVo.setReportCount(5);
            messageVo.setForwardingCount(13);

            return messageVo;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("查询消息详情失败！");
        }
        return null;
    }
}
